#include "bootpack.h"

/* CPUID 信息结构体 */

/* 内联函数执行 CPUID 指令 */
inline void get_cpuid(unsigned int Mop, unsigned int Sop, 
                      unsigned int *a, unsigned int *b, 
                      unsigned int *c, unsigned int *d)
{
    __asm__ __volatile__ (
        ".byte 0x0F, 0xA2\n\t"  // CPUID 机器码
        : "=a"(*a), "=b"(*b), "=c"(*c), "=d"(*d)
        : "0"(Mop), "2"(Sop)
    );
}

/* 获取完整的 CPU 信息 */
void get_cpu_info(struct CPU_INFO *info)
{
    unsigned int eax, ebx, ecx, edx;
    
    // 获取厂商ID
    get_cpuid(0, 0, &eax, &ebx, &ecx, &edx);
    info->max_func = eax;
    *((unsigned int *)&info->vendor_id[0]) = ebx;
    *((unsigned int *)&info->vendor_id[4]) = edx;
    *((unsigned int *)&info->vendor_id[8]) = ecx;
    info->vendor_id[12] = '\0';
    
    // 获取扩展功能支持
    get_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
    info->max_ext_func = eax;
    
    // 获取处理器特性标志
    get_cpuid(1, 0, &eax, &ebx, &ecx, &edx);
    info->features_ecx = ecx;
    info->features_edx = edx;
    
    // 获取品牌字符串（如果支持）
    if (info->max_ext_func >= 0x80000004) {
        get_cpuid(0x80000002, 0, 
            (unsigned int *)&info->brand_string[0],
            (unsigned int *)&info->brand_string[4],
            (unsigned int *)&info->brand_string[8],
            (unsigned int *)&info->brand_string[12]);
        
        get_cpuid(0x80000003, 0, 
            (unsigned int *)&info->brand_string[16],
            (unsigned int *)&info->brand_string[20],
            (unsigned int *)&info->brand_string[24],
            (unsigned int *)&info->brand_string[28]);
        
        get_cpuid(0x80000004, 0, 
            (unsigned int *)&info->brand_string[32],
            (unsigned int *)&info->brand_string[36],
            (unsigned int *)&info->brand_string[40],
            (unsigned int *)&info->brand_string[44]);
        
        info->brand_string[48] = '\0';
    } else {
        sprintf(info->brand_string, "Brand string not supported");
    }
}

/* 打印 CPU 信息 */
void print_cpu_info(int x, int y)
{
    struct CPU_INFO cpu_info;
    get_cpu_info(&cpu_info);
    
    // 打印厂商信息
    sprintf(s_buf, "Vendor ID: %s", cpu_info.vendor_id);
    putfonts8_asc_sht(sht_back, x, y, COL8_000000, COL8_FFFFFF, s_buf, strlen(s_buf));
    
    // 打印品牌信息
    sprintf(s_buf, "Brand: %s", cpu_info.brand_string);
    putfonts8_asc_sht(sht_back, x+28, y+28, COL8_000000, COL8_FFFFFF, s_buf, strlen(s_buf));
    
    // 打印功能支持
    putfonts8_asc_sht(sht_back, x, y, COL8_000000, COL8_FFFFFF, "Features:", 10);
    if (cpu_info.features_edx & (1 << 23)) putfonts8_asc_sht(sht_back, x, y+28*2, COL8_000000, COL8_FFFFFF, " - MMX", 10);
    if (cpu_info.features_edx & (1 << 25)) putfonts8_asc_sht(sht_back, x, y+28*3, COL8_000000, COL8_FFFFFF, " - SSE", 10);
    if (cpu_info.features_edx & (1 << 26)) putfonts8_asc_sht(sht_back, x, y+28*4, COL8_000000, COL8_FFFFFF, " - SSE2", 10);
    if (cpu_info.features_ecx & (1 << 0))  putfonts8_asc_sht(sht_back, x, y+28*5, COL8_000000, COL8_FFFFFF, " - SSE3", 10);
    if (cpu_info.features_ecx & (1 << 9))  putfonts8_asc_sht(sht_back, x, y+28*6, COL8_000000, COL8_FFFFFF, " - SSSE3", 11);
    if (cpu_info.features_ecx & (1 << 19)) putfonts8_asc_sht(sht_back, x, y+28*7, COL8_000000, COL8_FFFFFF, " - SSE4.1", 15);
    if (cpu_info.features_ecx & (1 << 20)) putfonts8_asc_sht(sht_back, x, y+28*8, COL8_000000, COL8_FFFFFF, " - SSE4.2", 15);
    if (cpu_info.features_ecx & (1 << 23)) putfonts8_asc_sht(sht_back, x, y+28*9, COL8_000000, COL8_FFFFFF, "POPCNT", 15);
    if (cpu_info.features_ecx & (1 << 28)) putfonts8_asc_sht(sht_back, x, y+28*10, COL8_000000, COL8_FFFFFF, " - AVX", 15);
    
    // 打印最大功能支持
    sprintf(s_buf, "Max Standard Func: 0x%x", cpu_info.max_func);
    putfonts8_asc_sht(sht_back, x, y+28*11, COL8_000000, COL8_FFFFFF, s_buf, strlen(s_buf));
    sprintf(s_buf, "Max Extended Func: 0x%x", cpu_info.max_ext_func);
    putfonts8_asc_sht(sht_back, x, y+28*12, COL8_000000, COL8_FFFFFF, s_buf, strlen(s_buf));
}
